package algo3.algothief.controlador;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

import algo3.algothief.excepcion.CasoNoIniciadoException;
import algo3.algothief.modelo.Juego;
import algo3.algothief.vista.VistaJuego;


public class ControladorDescripcion {
	
	private Juego juego;
	
	private VistaJuego vistaDelJuego;
	
	private HashMap<String, String> opcionesParaModificarLaDescripcion;
	private HashMap<String, String> opcionesParaSeleccionarUnaCaracteristica;
	private HashMap<String, String> opcionesParaDefinirQueCaracteristicaCorresponde;
	
//---------------------------------------------------------------------------------------------------------
	
	public ControladorDescripcion(Juego juegoActual, VistaJuego vista) {
		this.juego = juegoActual;
		
		this.vistaDelJuego = vista;
		
		this.opcionesParaModificarLaDescripcion = this.crearOpcionesParaModificarLaDescripcion();
		this.opcionesParaSeleccionarUnaCaracteristica = this.crearOpcionesParaSeleccionarUnaCaracteristica();
		this.opcionesParaDefinirQueCaracteristicaCorresponde = this.crearOpcionesParaDefinirQueCaracteristicaCorresponde();
	}
	
//---------------------------------------------------------------------------------------------------------

	private HashMap<String, String> crearOpcionesParaModificarLaDescripcion() {
		HashMap<String, String> opciones = new HashMap<String, String>();
	
		opciones.put(Integer.toString(1), "Modificar el sexo del sospechoso");
		opciones.put(Integer.toString(2), "Modificar el hobby del sospechoso");
		opciones.put(Integer.toString(3), "Modificar el cabello del sospechoso");
		opciones.put(Integer.toString(4), "Modificar la senia del sospechoso");
		opciones.put(Integer.toString(5), "Modificar el vehiculo del sospechoso");
			
		return opciones;
	}
	
	private HashMap<String, String> crearOpcionesParaSeleccionarUnaCaracteristica() {
		HashMap<String, String> opciones = new HashMap<String, String>();
	
		opciones.put("Modificar el sexo del sospechoso", "sexos posibles");
		opciones.put("Modificar el hobby del sospechoso", "hobbys posibles");
		opciones.put("Modificar el cabello del sospechoso", "cabellos posibles");
		opciones.put("Modificar la senia del sospechoso", "senias posibles");
		opciones.put("Modificar el vehiculo del sospechoso", "vehiculos posibles");
			
		return opciones;
	}
	
	private HashMap<String, String> crearOpcionesParaDefinirQueCaracteristicaCorresponde() {
		HashMap<String, String> opciones = new HashMap<String, String>();
		
		opciones.put("Modificar el sexo del sospechoso", "Sexo");
		opciones.put("Modificar el hobby del sospechoso", "Hobby");
		opciones.put("Modificar el cabello del sospechoso", "Cabello");
		opciones.put("Modificar la senia del sospechoso", "Senia");
		opciones.put("Modificar el vehiculo del sospechoso", "Vehiculo");
			
		return opciones;
	}
	
	
	
	private String procesarAccionAElegir(BufferedReader entradaDeTeclado) throws IOException{
		String entrada = entradaDeTeclado.readLine();
		
		String opcionParaVolverAlMenuPrincipal = Integer.toString(0);
		
		while ( (!opcionesParaModificarLaDescripcion.containsKey(entrada)) && (!opcionParaVolverAlMenuPrincipal.matches(entrada)) ) {
			VistaJuego.graficarMensajeDeOpcionElegidaIncorrecta(entradaDeTeclado);
			
			vistaDelJuego.graficarMenuDeModificacionDeLaDescripcionDelSospechoso(opcionesParaModificarLaDescripcion);
			entrada = entradaDeTeclado.readLine();
		}
			
		return opcionesParaModificarLaDescripcion.get(entrada);
	}
	
	private ArrayList<String[]> formatearParaGraficar(HashMap<String, String> caracteristicas) {
		ArrayList<String[]> caracteristicasFormateadas = new ArrayList<String[]>();
		
		String[] sexo = { "Sexo", caracteristicas.get("Sexo") };
		String[] hobby = { "Hobby", caracteristicas.get("Hobby") };
		String[] cabello = { "Cabello", caracteristicas.get("Cabello") };
		String[] senia = { "Senia", caracteristicas.get("Senia") };
		String[] vehiculo = { "Vehiculo", caracteristicas.get("Vehiculo") };
		
		caracteristicasFormateadas.add(sexo);
		caracteristicasFormateadas.add(hobby);
		caracteristicasFormateadas.add(cabello);
		caracteristicasFormateadas.add(senia);
		caracteristicasFormateadas.add(vehiculo);
		
		return caracteristicasFormateadas;
	}

	
	
	private HashMap<String, String> crearOpcionesDeCiertaCaracteristica(ArrayList<String> opcionesDeCaracteristica) {
		HashMap<String, String> opciones = new HashMap<String, String>();
		
		int cantidadDeOpciones = opcionesDeCaracteristica.size();
		for (int i = 0; i < cantidadDeOpciones; i++)
			opciones.put(Integer.toString(i + 1), opcionesDeCaracteristica.get(i));
		
		// Para poder dejar vacio el espacio de esa caracteristica.
		opciones.put(Integer.toString(cantidadDeOpciones + 1), "Nada");
		
		return opciones;
	}
	
	private String procesarCaracteristicaElegida(BufferedReader entradaDeTeclado, HashMap<String,String> opcionesDeCaracteristica) throws IOException{
		String entrada = entradaDeTeclado.readLine();
		
		String opcionParaVolverAlMenuPrincipal = Integer.toString(0);
		
		while ( (!opcionesDeCaracteristica.containsKey(entrada)) && (!opcionParaVolverAlMenuPrincipal.matches(entrada)) ) {
			VistaJuego.graficarMensajeDeOpcionElegidaIncorrecta(entradaDeTeclado);
			
			vistaDelJuego.graficarMenuDeEleccionDeNuevaCaracteristica(opcionesDeCaracteristica);
			entrada = entradaDeTeclado.readLine();
		}
			
		return opcionesDeCaracteristica.get(entrada);
	}
	
	private HashMap<String, String> obtenerOpcionesParaModificarCiertaCaracteristica(String eleccion, HashMap<String, ArrayList<String>> posiblesOpciones) {
		String caracteristicaAModificar = opcionesParaSeleccionarUnaCaracteristica.get(eleccion);
		ArrayList<String> posiblesCaracteristicasNuevas = posiblesOpciones.get(caracteristicaAModificar);
		HashMap<String, String> opcionesDeLaCaracteristica = this.crearOpcionesDeCiertaCaracteristica(posiblesCaracteristicasNuevas);
		
		return opcionesDeLaCaracteristica;
	}
	
//---------------------------------------------------------------------------------------------------------

	public void procesarEntradasParaModificarLaDescripcionDelSospechoso(BufferedReader entradaDeTeclado) throws IOException, CasoNoIniciadoException {
		HashMap<String, String> caracteristicas = juego.verLasCaracteristicasDelSospechoso();
		ArrayList<String[]> caracteristicasFormateadas = this.formatearParaGraficar(caracteristicas);
		vistaDelJuego.graficarDescripcionDelSospechosoActual(caracteristicasFormateadas);
		
		vistaDelJuego.graficarMenuDeModificacionDeLaDescripcionDelSospechoso(opcionesParaModificarLaDescripcion);
		String eleccion = this.procesarAccionAElegir(entradaDeTeclado);
		
		while (eleccion != null) {
			HashMap<String, ArrayList<String>> posiblesOpciones = juego.verLasPosiblesOpcionesParaModificarLaDescripcionDelSospechoso();
			
			caracteristicasFormateadas = this.formatearParaGraficar(caracteristicas);
			vistaDelJuego.graficarDescripcionDelSospechosoActual(caracteristicasFormateadas);
			
			HashMap<String, String> opcionesDeLaCaracteristica = this.obtenerOpcionesParaModificarCiertaCaracteristica(eleccion, posiblesOpciones);
			
			String caracteristica = opcionesParaDefinirQueCaracteristicaCorresponde.get(eleccion);
			
			vistaDelJuego.graficarMenuDeEleccionDeNuevaCaracteristica(opcionesDeLaCaracteristica);
			String nuevaCaracteristica = this.procesarCaracteristicaElegida(entradaDeTeclado, opcionesDeLaCaracteristica);
			
			if (nuevaCaracteristica != null) { 
				caracteristicas.put(caracteristica, nuevaCaracteristica);
				if (nuevaCaracteristica.matches("Nada"))
					caracteristicas.put(caracteristica, null);
			}
			
			
			caracteristicasFormateadas = this.formatearParaGraficar(caracteristicas);
			vistaDelJuego.graficarDescripcionDelSospechosoActual(caracteristicasFormateadas);
			
			vistaDelJuego.graficarMenuDeModificacionDeLaDescripcionDelSospechoso(opcionesParaModificarLaDescripcion);
			eleccion = this.procesarAccionAElegir(entradaDeTeclado);
		}
		
		juego.modificarLaDescripcionDelSospechoso(caracteristicas);
	}
}
